/*
    抽象层：采用虚接口方式抽象底层实现，实现了接口与实现的分离，提供统一接口供上层调用
            支持多态行为并增强了模块的可替换性与可维护性
        1、消息类抽象、协议类抽象、缓冲区类抽象、连接类抽象、服务端类抽象、客户端类抽象

*/
#pragma once
#include <string>
#include <memory>
#include <functional>
#include "fields.hpp"

namespace ns_jsonrpc
{
    // 消息抽象类
    class BaseMessage
    {
    public:
        using BaseMessagePtr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage()
        {}
        
        // 设置请求id
        virtual void setId(const std::string &id)
        {
            _id = id;
        }

        // 获取请求id
        virtual std::string id()
        {
            return _id;
        }

        // 设置消息类型
        virtual void setMType(MType mtype)
        {
            _mtype = mtype;
        }

        // 获取消息类型
        virtual MType mType()
        {
            return _mtype;
        }

        virtual std::string serialize() = 0;                          // 序列化
        virtual bool unSerialize(const std::string &bodyJsonStr) = 0; // 反序列化
        virtual bool check() = 0;                                     // 检查反序列化后的消息格式是否完整

    private:
        std::string _id; // 请求id
        MType _mtype;    // 请求类型
    };

    // 缓存抽象类
    class BaseBuffer
    {
    public:
        using BaseBufferPtr = std::shared_ptr<BaseBuffer>;
        virtual size_t readableBytes() = 0;                   // 获取缓冲区可读字节数
        virtual int32_t peekInt32() = 0;                      // 查看缓冲区前4个字节，不删除数据
        virtual void retrieveInt32() = 0;                     // 删除缓冲区前4个字节
        virtual int32_t readInt32() = 0;                      // 读取缓冲区前前4个字节，并删除数据
        virtual std::string retrieveAsString(size_t len) = 0; // 读取缓冲区指定长度的字符串
    };

    // 应用层协议抽象类
    class BaseProtocol
    {
    public:
        using BaseProtocolPtr = std::shared_ptr<BaseProtocol>;
        virtual bool canProcessed(const BaseBuffer::BaseBufferPtr &buf) = 0;                                // 是否可以处理缓冲区中的请求
        virtual bool onMessage(const BaseBuffer::BaseBufferPtr &buf, BaseMessage::BaseMessagePtr &msg) = 0; // 收到消息时处理函数
        virtual std::string serialize(const BaseMessage::BaseMessagePtr &msg) = 0;                          // 将消息序列化为标准协议格式
    };

    // 连接抽象类
    class BaseConnection
    {
    public:
        using BaseConnectionPtr = std::shared_ptr<BaseConnection>;
        virtual bool connected() = 0;                                  // 获取连接状态
        virtual void shutdown() = 0;                                   // 关闭连接
        virtual void send(const BaseMessage::BaseMessagePtr &msg) = 0; // 发送消息
    };

    using ConnectionCallback = std::function<void(const BaseConnection::BaseConnectionPtr &)>;
    using CloseCallback = std::function<void(const BaseConnection::BaseConnectionPtr &)>;
    using MessageCallback = std::function<void(const BaseConnection::BaseConnectionPtr &, BaseMessage::BaseMessagePtr &)>;
    // 服务器抽象类
    class BaseServer
    {
    public:
        using BaseServerPtr = std::shared_ptr<BaseServer>;
        virtual void setConnectionCallback(const ConnectionCallback &cb) // 设置连接建立回调
        {
            _cb_connection = cb;
        }

        virtual void setCloseCallback(const CloseCallback &cb) // 设置连接断开回调
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb) // 设置消息回调
        {
            _cb_message = cb;
        }
        virtual void start() = 0; // 启动服务

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

    // 客户端抽象类
    class BaseClient
    {
    public:
        using BaseClientPtr = std::shared_ptr<BaseClient>;
        virtual void setConnectionCallback(const ConnectionCallback &cb) // 设置连接建立回调
        {
            _cb_connection = cb;
        }

        virtual void setCloseCallback(const CloseCallback &cb) // 设置连接断开回调
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb) // 设置消息回调
        {
            _cb_message = cb;
        }
        virtual void connect() = 0;                                    // 连接
        virtual void shutdown() = 0;                                   // 关闭连接
        virtual BaseConnection::BaseConnectionPtr connection() = 0;    // 获取连接
        virtual bool connected() = 0;                                  // 获取连接状态
        virtual bool send(const BaseMessage::BaseMessagePtr &msg) = 0; // 发送消息

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
}